package com.uinnova.product.eam.service.utils;

import com.alibaba.fastjson.JSON;
import com.binary.core.util.BinaryUtils;
import com.uinnova.product.eam.model.diagram.DiagramNodeLinkInfo;
import com.uinnova.product.eam.model.diagram.VisualModelJson;
import com.uinnova.product.eam.model.diagram.VisualModelLink;
import com.uinnova.product.eam.model.diagram.VisualModelNode;
import com.uino.bean.cmdb.base.ESVisualModel;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 元模型工具类
 */
public class VisualModelUtils {

    /**
     * 获取元模型所有在用分类id
     * @param visualModel 在用元模型
     * @return 分类id
     */
    public static Set<Long> getCiClassIds(ESVisualModel visualModel){
        Set<Long> result = new HashSet<>();
        if(BinaryUtils.isEmpty(visualModel.getJson())){
            return result;
        }
        List<VisualModelJson> modelJsonList = JSON.parseArray(visualModel.getJson(), VisualModelJson.class);
        for (VisualModelJson json : modelJsonList) {
            if (BinaryUtils.isEmpty(json.getNodeDataArray())) {
                continue;
            }
            for (VisualModelNode node : json.getNodeDataArray()) {
                if(BinaryUtils.isEmpty(node.getClassId())){
                    continue;
                }
                result.add(node.getClassId());
            }
        }
        return result;
    }

    /**
     * 获取分类在元模型中下级分类id
     * @param visualModel 在用元模型
     * @return 分类id
     */
    public static Set<Long> getLowerClassIds(ESVisualModel visualModel, Long classId){
        Set<Long> result = new HashSet<>();
        if(BinaryUtils.isEmpty(visualModel.getJson())){
            return result;
        }
        List<VisualModelJson> modelJsonList = JSON.parseArray(visualModel.getJson(), VisualModelJson.class);
        for (VisualModelJson json : modelJsonList) {
            if (CollectionUtils.isEmpty(json.getNodeDataArray()) || CollectionUtils.isEmpty(json.getLinkDataArray())) {
                continue;
            }
            Map<Long, Long> nodeMap = json.getNodeDataArray().stream().filter(e -> !BinaryUtils.isEmpty(e.getClassId())).collect(Collectors.toMap(VisualModelNode::getKey, VisualModelNode::getClassId));
            for (VisualModelLink link : json.getLinkDataArray()) {
                Long from = nodeMap.get(link.getFrom());
                Long to = nodeMap.get(link.getTo());
                if(from == null || to == null || !from.equals(classId)){
                    continue;
                }
                result.add(to);
            }
        }
        return result;
    }

    /**
     * 获取元模型关系分类
     * @param visualModel 元模型
     * @return 关系分类
     */
    public static List<DiagramNodeLinkInfo> getRltClassIds(ESVisualModel visualModel){
        List<DiagramNodeLinkInfo> result = new ArrayList<>();
        if(BinaryUtils.isEmpty(visualModel.getJson())){
            return result;
        }
        List<VisualModelJson> modelJsonList = JSON.parseArray(visualModel.getJson(), VisualModelJson.class);
        //获取元模型中关系
        for (VisualModelJson modelJson : modelJsonList) {
            List<VisualModelNode> nodeList = modelJson.getNodeDataArray();
            List<VisualModelLink> linkList = modelJson.getLinkDataArray();
            if(BinaryUtils.isEmpty(nodeList) || BinaryUtils.isEmpty(linkList)){
                continue;
            }
            Map<Long, VisualModelNode> nodeMap = nodeList.stream().collect(Collectors.toMap(VisualModelNode::getKey, each -> each, (k1, k2) -> k2));
            for (VisualModelLink link : linkList) {
                VisualModelNode from = nodeMap.get(link.getFrom());
                VisualModelNode to = nodeMap.get(link.getTo());
                if(from == null || BinaryUtils.isEmpty(from.getClassId()) || to == null ||
                        BinaryUtils.isEmpty(to.getClassId()) || BinaryUtils.isEmpty(link.getClassId())){
                    continue;
                }
                result.add(new DiagramNodeLinkInfo(from.getClassId(), to.getClassId(), link.getClassId()));
            }
        }
        return result;
    }

}
